home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / ttydriv.c < prev    next >
C/C++ Source or Header  |  1991-06-29  |  6KB  |  256 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  * split screen by G. J. van der Grinten, PA0GRI
  4.  */
  5. #include <stdio.h>
  6. #ifdef __TURBOC__
  7. #include <conio.h>
  8. #endif
  9. #include <ctype.h>
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "session.h"
  13. #include "tty.h"
  14. #include "socket.h"
  15.  
  16. extern FILE *Rawterm;
  17.  
  18. #define    OFF    0
  19. #define    ON    1
  20.  
  21. static int  Lastsize = 1;
  22. static char Lastline[LINESIZE+1] = "\n";
  23. #define    CTLU    21        /* delete current line in total */
  24. #define    CTLR    18        /* reprint current line */
  25. #define    CTLZ    26        /* EOF char in dos */
  26. #define    CTLW    23        /* erase last word including preceding space */
  27. #define    CTLB    02        /* use as F3 in dos but no editing */
  28. #define DEL    0x7f
  29.  
  30. /* Accept characters from the incoming tty buffer and process them
  31.  * (if in cooked mode) or just pass them directly (if in raw mode).
  32.  *
  33.  * Echoing (if enabled) is direct to the raw terminal. This requires
  34.  * recording (if enabled) of locally typed info to be done by the session
  35.  * itself so that edited output instead of raw input is recorded.
  36.  * Control-W added by g1emm again.... for word delete.
  37.  * Control-B/Function key 3 added by g1emm for line repeat.
  38.  */
  39.  
  40. struct mbuf *
  41. ttydriv(sp,c)
  42. struct session *sp;
  43. char c;
  44. {
  45.     struct mbuf *bp;
  46.     char *cp,*rp;
  47.     int cnt;
  48.  
  49.     switch(sp->ttystate.edit){
  50.     case OFF:
  51.         bp = ambufw(1);
  52.         *bp->data = c;
  53.         bp->cnt = 1;
  54.         if(sp->ttystate.echo){
  55.             if(sp->split){
  56.                 sp->tsavex = wherex();
  57.                 sp->tsavey = wherey();
  58.                 window(1,24,80,25);
  59.                 gotoxy(sp->bsavex,sp->bsavey);
  60.                 highvideo();
  61.                 putch(c);
  62.                 normvideo();
  63.                 cputs("_\b");
  64.                 sp->bsavex = wherex();
  65.                 sp->bsavey = wherey();
  66.                 window(1,1,80,23);
  67.                 gotoxy(sp->tsavex,sp->tsavey);
  68.             } else {
  69.                 putc(c,Rawterm);
  70.             }
  71.         }
  72.         return bp;
  73.     case ON:
  74.         if(sp->ttystate.line == NULLBUF)
  75.             sp->ttystate.line = ambufw(LINESIZE);
  76.  
  77.         bp = sp->ttystate.line;
  78.         cp = bp->data + bp->cnt;
  79.         /* Perform cooked-mode line editing */
  80.         switch(c & 0x7f){
  81.         case '\r':    /* CR and LF both terminate the line */
  82.         case '\n':
  83.             if(sp->ttystate.crnl)
  84.                 *cp = '\n';
  85.             else
  86.                 *cp = c;
  87.             if(sp->ttystate.echo){
  88.                 if(sp->split){
  89.                     highvideo();
  90.                     rp = bp->data;
  91.                     while(rp < cp) {
  92.                         putch(*rp++);
  93.                     }
  94.                     normvideo();
  95.                     clreol();
  96.                     cputs(Eol);
  97.                     clreol();
  98.                     sp->tsavex = wherex();
  99.                     sp->tsavey = wherey();
  100.                     window(1,24,80,25);
  101.                     clrscr();
  102.                     cputs("_\b");
  103.                     sp->bsavex = wherex();
  104.                     sp->bsavey = wherey();
  105.                     window(1,1,80,23);
  106.                     gotoxy(sp->tsavex,sp->tsavey);
  107.                 } else {
  108.                     fputs(Eol,Rawterm);
  109.                 }
  110.             }
  111.             bp->cnt += 1;
  112.             sp->ttystate.line = NULLBUF;
  113.             Lastsize = bp->cnt;
  114.             memcpy(Lastline, bp->data, Lastsize);            
  115.             return bp;
  116.         case DEL:
  117.         case '\b':    /* Character delete */
  118.             if(bp->cnt != 0){
  119.                 bp->cnt--;
  120.                 if(sp->ttystate.echo){
  121.                     if(sp->split){
  122.                         sp->tsavex = wherex();
  123.                         sp->tsavey = wherey();
  124.                         window(1,24,80,25);
  125.                         gotoxy(sp->bsavex,sp->bsavey);
  126.                         cputs(" \b\b_\b");
  127.                         sp->bsavex = wherex();
  128.                         sp->bsavey = wherey();
  129.                         window(1,1,80,23);
  130.                         gotoxy(sp->tsavex,sp->tsavey);
  131.                     } else {
  132.                         fputs("\b \b",Rawterm);
  133.                     }
  134.                 }
  135.             }
  136.             break;
  137.         case CTLR:    /* print line buffer */
  138.             if(sp->ttystate.echo){
  139.                 if(sp->split) {
  140.                     sp->tsavex = wherex();
  141.                     sp->tsavey = wherey();
  142.                     window(1,24,80,25);
  143.                     gotoxy(sp->bsavex,sp->bsavey);
  144.                     clrscr();
  145.                     rp = bp->data;
  146.                     while (rp < cp)
  147.                         putch(*rp++) ;
  148.                     cputs("_\b");
  149.                     sp->bsavex = wherex();
  150.                     sp->bsavey = wherey();
  151.                     window(1,1,80,23);
  152.                     gotoxy(sp->tsavex,sp->tsavey);
  153.                 } else {
  154.                     fprintf(Rawterm,"^R%s",Eol) ;
  155.                     rp = bp->data;
  156.                     while (rp < cp)
  157.                         putc(*rp++,Rawterm) ;
  158.                 }
  159.             }
  160.             break ;
  161.         case CTLU:    /* Line kill */
  162.             if(sp->split) {
  163.                 sp->tsavex = wherex();
  164.                 sp->tsavey = wherey();
  165.                 window(1,24,80,25);
  166.                 gotoxy(sp->bsavex,sp->bsavey);
  167.                 cputs(" \b");
  168.                 while(bp->cnt != 0){
  169.                     cputs("\b \b");
  170.                     bp->cnt--;
  171.                 }
  172.                 cputs("_\b");
  173.                 sp->bsavex = wherex();
  174.                 sp->bsavey = wherey();
  175.                 window(1,1,80,23);
  176.                 gotoxy(sp->tsavex,sp->tsavey);
  177.             } else {
  178.                 while(bp->cnt != 0){
  179.                     bp->cnt--;
  180.                     if(sp->ttystate.echo)
  181.                         fputs("\b \b",Rawterm);
  182.                 }
  183.             }
  184.             break;
  185.         case CTLB:    /* Use last line to finish current */
  186.             cnt = bp->cnt;        /* save count so far */
  187.  
  188.             while(bp->cnt != 0){
  189.                 bp->cnt--;
  190.                 if(sp->ttystate.echo)
  191.                     fputs("\b \b", Rawterm);
  192.             }
  193.             bp->cnt = cnt;
  194.  
  195.                         if(bp->cnt < (Lastsize-1)){
  196.                                 memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
  197.                                 bp->cnt = Lastsize-1;
  198.             }
  199.  
  200.             *(bp->data + bp->cnt) = '\0';    /* make it a string */
  201.             if(sp->ttystate.echo)
  202.                 fputs(bp->data, Rawterm);    /* repaint line */
  203.             break ;
  204.         case CTLW:    /* erase word */
  205.             cnt = 0 ;    /* we haven't seen a printable char yet */
  206.             while(bp->cnt != 0){
  207.                 *(bp->data + bp->cnt--) = '\n';
  208.                 if(sp->ttystate.echo)
  209.                     fputs("\b \b", Rawterm);
  210.                 if (isspace((int)*(bp->data + bp->cnt))) {
  211.                     if (cnt)
  212.                         break ;
  213.                 } else {
  214.                     cnt = 1 ;
  215.                 }
  216.             }
  217.             break ;
  218.         default:    /* Ordinary character */
  219.             *cp = c;
  220.             bp->cnt++;
  221.  
  222.             /* ^Z apparently hangs the terminal emulators under
  223.              * DoubleDos and Desqview. I REALLY HATE having to patch
  224.              * around other people's bugs like this!!!
  225.              */
  226.             if(sp->ttystate.echo &&
  227. #ifndef    AMIGA
  228.              c != CTLZ &&
  229. #endif
  230.              bp->cnt < LINESIZE-1){
  231.                 if(sp->split) {
  232.                     sp->tsavex = wherex();
  233.                     sp->tsavey = wherey();
  234.                     window(1,24,80,25);
  235.                     gotoxy(sp->bsavex,sp->bsavey);
  236.                     putch(c);
  237.                     cputs("_\b");
  238.                     sp->bsavex = wherex();
  239.                     sp->bsavey = wherey();
  240.                     window(1,1,80,23);
  241.                     gotoxy(sp->tsavex,sp->tsavey);
  242.                 } else {
  243.                     putc(c,Rawterm);
  244.                 }
  245.  
  246.             } else if(bp->cnt >= LINESIZE-1){
  247.                 putc('\007',Rawterm);    /* Beep */
  248.                 bp->cnt--;
  249.             }
  250.             break;
  251.         }
  252.         break;
  253.     }
  254.     return NULLBUF;
  255. }
  256.